import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.MatteBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class SudokuSolver {
    private JTextField[][] cells = new JTextField[9][9];

    public static void main(String[] args) {
        new SudokuSolver().createUI();
    }

    private void createUI() {
        JFrame frame = new JFrame("数独求解器");
        frame.setSize(600, 650);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());

        JPanel boardPanel = new JPanel();
        boardPanel.setLayout(new GridLayout(9, 9));
        boardPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

        // 创建9x9的文本框网格
        for (int row = 0; row < 9; row++) {
            for (int col = 0; col < 9; col++) {
                JTextField cell = new JTextField();
                cell.setHorizontalAlignment(JTextField.CENTER);
                cell.setFont(new Font("Arial", Font.BOLD, 20));

                // 设置3x3宫格的边框
                Border defaultBorder = BorderFactory.createLineBorder(Color.GRAY, 1);
                cell.setBorder(defaultBorder);

                // 加强3x3宫格的边框
                if (row % 3 == 0 && row != 0) {
                    Border topBorder = BorderFactory.createMatteBorder(2, 0, 0, 0, Color.BLACK);
                    cell.setBorder(BorderFactory.createCompoundBorder(topBorder, defaultBorder));
                }
                if (col % 3 == 0 && col != 0) {
                    Border leftBorder = BorderFactory.createMatteBorder(0, 2, 0, 0, Color.BLACK);
                    cell.setBorder(BorderFactory.createCompoundBorder(leftBorder, cell.getBorder()));
                }

                cells[row][col] = cell;
                boardPanel.add(cell);
            }
        }

        JButton solveButton = new JButton("求解");
        solveButton.setFont(new Font("Arial", Font.BOLD, 20));
        solveButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                solveSudoku();
            }
        });

        JButton clearButton = new JButton("清空");
        clearButton.setFont(new Font("Arial", Font.BOLD, 20));
        clearButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                clearBoard();
            }
        });

        JPanel buttonPanel = new JPanel();
        buttonPanel.add(solveButton);
        buttonPanel.add(clearButton);

        frame.add(boardPanel, BorderLayout.CENTER);
        frame.add(buttonPanel, BorderLayout.SOUTH);
        frame.setVisible(true);
    }

    private void solveSudoku() {
        int[][] board = new int[9][9];

        // 读取用户输入
        try {
            for (int row = 0; row < 9; row++) {
                for (int col = 0; col < 9; col++) {
                    String text = cells[row][col].getText();
                    if (text != null && !text.isEmpty()) {
                        int num = Integer.parseInt(text);
                        if (num < 1 || num > 9) {
                            JOptionPane.showMessageDialog(null,
                                    "请输入1-9之间的数字", "输入错误", JOptionPane.ERROR_MESSAGE);
                            return;
                        }
                        board[row][col] = num;
                    } else {
                        board[row][col] = 0; // 0表示空格
                    }
                }
            }
        } catch (NumberFormatException e) {
            JOptionPane.showMessageDialog(null,
                    "请输入有效的数字", "输入错误", JOptionPane.ERROR_MESSAGE);
            return;
        }

        // 尝试求解数独
        if (solve(board)) {
            // 显示解
            for (int row = 0; row < 9; row++) {
                for (int col = 0; col < 9; col++) {
                    if (cells[row][col].getText().isEmpty()) {
                        cells[row][col].setText(String.valueOf(board[row][col]));
                        cells[row][col].setForeground(Color.BLUE); // 解用蓝色显示
                    }
                }
            }
        } else {
            JOptionPane.showMessageDialog(null,
                    "无法找到解，请检查输入", "求解失败", JOptionPane.WARNING_MESSAGE);
        }
    }

    // 数独求解算法（回溯法）
    private boolean solve(int[][] board) {
        for (int row = 0; row < 9; row++) {
            for (int col = 0; col < 9; col++) {
                if (board[row][col] == 0) {
                    for (int num = 1; num <= 9; num++) {
                        if (isValid(board, row, col, num)) {
                            board[row][col] = num;
                            if (solve(board)) {
                                return true;
                            } else {
                                board[row][col] = 0; // 回溯
                            }
                        }
                    }
                    return false; // 触发回溯
                }
            }
        }
        return true; // 所有格子已填满
    }

    // 检查数字是否有效
    private boolean isValid(int[][] board, int row, int col, int num) {
        // 检查行
        for (int x = 0; x < 9; x++) {
            if (board[row][x] == num) return false;
        }

        // 检查列
        for (int x = 0; x < 9; x++) {
            if (board[x][col] == num) return false;
        }

        // 检查3x3宫格
        int startRow = row - row % 3;
        int startCol = col - col % 3;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (board[startRow + i][startCol + j] == num) return false;
            }
        }

        return true;
    }

    private void clearBoard() {
        for (int row = 0; row < 9; row++) {
            for (int col = 0; col < 9; col++) {
                cells[row][col].setText("");
                cells[row][col].setForeground(Color.BLACK);
            }
        }
    }
}